/* * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.angrybyte.numberpicker.utils;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.app.Context;
import ohos.global.resource.*;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;

public class ResUtil {
    private static final String TAG = ResUtil.class.getSimpleName();
    public static final float FLOAT_HALF = 0.5f;

    private ResUtil() {}

    /**
     * get the path from id
     *
     * @param context the context
     * @param id      the id
     * @return the path from id
     */
    public static String getPathById(Context context, int id) {
        String path = "";
        if (context == null) {
            LogUtil.error(TAG, "getPathById -> get null context");
            return path;
        }
        ResourceManager manager = context.getResourceManager();
        if (manager == null) {
            LogUtil.error(TAG, "getPathById -> get null ResourceManager");
            return path;
        }
        try {
            path = manager.getMediaPath(id);
        } catch (IOException | NotExistException | WrongTypeException e) {
            LogUtil.error(TAG, "getPathById -> Exception: " + e.getMessage());
        }
        return path;
    }

    /**
     * get the dimen value
     *
     * @param context the context
     * @param id      the id
     * @return get the float dimen value
     */
    public static float getDimen(Context context, int id) {
        float result = 0;
        if (context == null) {
            LogUtil.error(TAG, "getDimen -> get null context");
            return result;
        }
        ResourceManager manager = context.getResourceManager();
        if (manager == null) {
            LogUtil.error(TAG, "getDimen -> get null ResourceManager");
            return result;
        }
        try {
            result = manager.getElement(id).getFloat();
        } catch (IOException | NotExistException | WrongTypeException e) {
            LogUtil.error(TAG, "getDimen -> Exception: " + e.getMessage());
        }
        return result;
    }

    /**
     * get the dimen value
     *
     * @param context the context
     * @param id      the id
     * @return get the int dimen value
     */
    public static int getIntDimen(Context context, int id) {
        float value = getDimen(context, id);
        return (int) (value >= 0 ? value + FLOAT_HALF : value - FLOAT_HALF);
    }

    /**
     * get the pixel map
     *
     * @param context the context
     * @param id      the id
     * @return the pixel map
     */
    public static Optional<PixelMap> getPixelMap(Context context, int id) {
        String path = getPathById(context, id);
        if (path.isEmpty()) {
            LogUtil.error(TAG, "getPixelMap -> get empty path");
            return Optional.empty();
        }
        RawFileEntry assetManager = context.getResourceManager().getRawFileEntry(path);
        ImageSource.SourceOptions options = new ImageSource.SourceOptions();
        options.formatHint = "image/png";
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        try {
            Resource asset = assetManager.openRawFile();
            ImageSource source = ImageSource.create(asset, options);
            return Optional.ofNullable(source.createPixelmap(decodingOptions));
        } catch (IOException e) {
            LogUtil.error(TAG, "getPixelMap -> Exception: " + e.getMessage());
        }
        return Optional.empty();
    }

    /**
     * get the Pixel Map Element
     *
     * @param context the context
     * @param resId   the res id
     * @return the Pixel Map Element
     */
    public static PixelMapElement getPixelMapDrawable(Context context, int resId) {
        Optional<PixelMap> optional = getPixelMap(context, resId);
        return optional.map(PixelMapElement::new).orElse(null);
    }

    /**
     * get the Element
     *
     * @param color the color
     * @return the Element
     */
    public static ShapeElement buildDrawableByColor(int color) {
        ShapeElement drawable = new ShapeElement();
        drawable.setShape(ShapeElement.RECTANGLE);
        drawable.setRgbColor(RgbColor.fromArgbInt(color));
        return drawable;
    }

    public static PixelMap createPixelmap(int width, int height,  PixelFormat config) {
        PixelMap.InitializationOptions opts = new PixelMap.InitializationOptions();
        opts.size = new Size(width, height);
        opts.pixelFormat = config;

        return PixelMap.create( opts);
    }

    public static PixelMap getDrawable(Context ourContext, int id, ImageSource.DecodingOptions decodingOptions) {
        ResourceManager rm = ourContext.getResourceManager();
        try {
            InputStream is =rm.getResource(id);
            PixelMap pixelmap = decodePixelMap(is, decodingOptions, "image/png");
            is.close();
            return pixelmap;
        } catch (NotExistException | IOException exception) {
            LogUtil.error(TAG, "getDrawable -> Exception: " + exception.getMessage());
            return null;
        }
    }

    public static PixelMap decodePixelMap(InputStream is, ImageSource.DecodingOptions options, String formatHint)throws IOException{
        ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
        srcOpts.formatHint = formatHint;
        ImageSource imageSource =ImageSource.create(is, srcOpts);
        if (imageSource == null) {
            throw new FileNotFoundException();
        }
        return imageSource.createPixelmap(options);
    }
}